package dimensional.traveler.server.services;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;

import com.google.inject.Inject;

import dimensional.traveler.client.services.CareerService;
import dimensional.traveler.server.model.Career;
import dimensional.traveler.server.model.User;
import dimensional.traveler.server.persistence.CharacterClassRepository;
import dimensional.traveler.server.persistence.MissionRepository;
import dimensional.traveler.server.persistence.UserRepository;
import dimensional.traveler.shared.model.Mission;
import dimensional.traveler.shared.model.missionSequence.MissionEndDetails;
import dimensional.traveler.shared.model.missionSequence.MissionSequence;

public class CareerServiceImpl implements CareerService {

	@Inject
	UserRepository userRepository;
	@Inject
	CharacterClassRepository characterClassRepository;
	@Inject
	MissionRepository missionRepository;
	
	@Override
	public MissionSequence startNewCareer(String userName) {
		return startMission(userName, "tutorial");
	}

	private void autosaveProgress(User user) {
		saveProgress(user, "Autosave");
	}
	
	private void saveProgress(User user, String saveName){
		String saveDirPath = "saves/" + user.getUserName();
		File saveDirectory = new File(saveDirPath);
		createFolders(saveDirectory);
		String saveFile = saveDirPath + "/" + saveName;
		try {
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(saveFile));
			objectOutputStream.writeObject(user.getActiveCareer());
			objectOutputStream.close();
		} catch (IOException e) {
			// TODO save was not successful
			e.printStackTrace();
		}
	}

	private void createFolders(File saveDirectory) {
		if (!saveDirectory.isDirectory())
			saveDirectory.mkdirs();
	}

	@Override
	public Collection<Mission> getNewMissions(String userName) {
		User user = userRepository.getUserByUserName(userName);
		return user.getActiveCareer().getNewMissions();
	}

	@Override
	public Collection<Mission> getReplayableMissions(String userName) {
		User user = userRepository.getUserByUserName(userName);
		return user.getActiveCareer().getOldMissions();
	}

	@Override
	public void saveProgress(String userName, String saveGameName) {
		User user = userRepository.getUserByUserName(userName);
		saveProgress(user, saveGameName);
	}

	@Override
	public void loadGame(String loggedInUser, String saveGameName) {
		User user = userRepository.getUserByUserName(loggedInUser);
		String saveDirPath = "saves/" + user.getUserName() + "/" + saveGameName;
		File file = new File(saveDirPath);
		loadSaveFileForUser(user, file);
		
	}

	private void loadSaveFileForUser(User user, File file) {
		try {
			ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
			Career career = (Career) objectInputStream.readObject();
			user.setActiveCareer(career);
			objectInputStream.close();
		} catch (IOException | ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void loadLastGame(String loggedInUser) {
		User user = userRepository.getUserByUserName(loggedInUser);
		String saveDirPath = "saves/" + user.getUserName();
		File saveDirectory = new File(saveDirPath);
		File[] files = saveDirectory.listFiles();
		File lastGame = files[0];
		for (File save : files){
			if (save.lastModified() > lastGame.lastModified()){
				lastGame = save;
			}
		}
		loadSaveFileForUser(user, lastGame);
	}

	@Override
	public MissionSequence startMission(String userName, String missionId) {
		User user = userRepository.getUserByUserName(userName);
		Mission mission = missionRepository.getMissionById(missionId);
		
		Career activeCareer = user.getActiveCareer();
		if (activeCareer == null){
			activeCareer = new Career();
			user.setActiveCareer(activeCareer);
		}
		activeCareer.setActiveMission(mission);
		
		autosaveProgress(user);
		
		return mission.getNextMissionSequence();
	}

	@Override
	public MissionSequence setCharacterClassId(String userName, String characterClassId) {
		User user = userRepository.getUserByUserName(userName);
		Career activeCareer = user.getActiveCareer();
		activeCareer.resetUserCharacter(characterClassId);
		
		Mission activeMission = activeCareer.getActiveMission();
		return activeMission.getNextMissionSequence();
	}

	@Override
	public MissionSequence getNextMissionSequence(String userName) {
		User user = userRepository.getUserByUserName(userName);
		Career activeCareer = user.getActiveCareer();
		Mission activeMission = activeCareer.getActiveMission();
		MissionSequence nextMissionSequence = activeMission.getNextMissionSequence();
		
		if (nextMissionSequence instanceof MissionEndDetails){
			if (activeMission.isVictorious()){
				// move mission to replayable
				// update career with new shops, trainers etc
			} else {
				// nothing as of yet...
			}
			activeCareer.setActiveMission(null);
		}
		
		return nextMissionSequence;
	}
	
}
